package com.naiterui.ehp.bs.cms.modules.inventory.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.naiterui.ehp.bs.cms.common.vo.PageParamsVO;
import com.naiterui.ehp.bs.cms.common.vo.PageVO;
import com.naiterui.ehp.bs.cms.modules.inventory.entity.Inventory;
import com.naiterui.ehp.bs.cms.modules.inventory.mapper.InventoryMapper;
import com.naiterui.ehp.bs.cms.modules.inventory.service.IInventoryService;
import com.naiterui.ehp.bs.cms.modules.inventory.vo.InventoryVO;
import com.naiterui.ehp.bs.cms.modules.inventory.vo.InventoryWaterVO;
import com.naiterui.ehp.bs.cms.modules.inventory.vo.SkuInventoryVO;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class InventoryServiceImpl extends ServiceImpl<InventoryMapper, Inventory> implements IInventoryService {

  @Override
  public PageVO<SkuInventoryVO> queryPage(PageParamsVO pageParamsVO, SkuInventoryVO skuInventory) {
    QueryWrapper<SkuInventoryVO> entityWrapper = this.buildEntityWrapper(pageParamsVO, skuInventory);

    Page<SkuInventoryVO> page = this.baseMapper.getPage(pageParamsVO.getPage(), entityWrapper);
    page.getRecords().forEach(inventory -> {
      String skuNumber = inventory.getSkuNumber();
      List<InventoryVO> list = this.baseMapper.getInventoryBySku(skuNumber);
      list.forEach(inventoryVO -> inventoryVO.setTotalQuantity(
          inventoryVO.getPhysicalQuantity() - inventoryVO.getWillQuantity() - inventoryVO.getTakeUpQuantity()));

      inventory.setInventors(list);

      long totalPhysicalQuantity = list.stream()
          .filter(inventoryVO -> inventoryVO.getStatus() == 0)
          .mapToLong(InventoryVO::getPhysicalQuantity)
          .sum();
      inventory.setTotalPhysicalQuantity(totalPhysicalQuantity);

      long totalWillQuantity = list.stream().filter(inventoryVO -> inventoryVO.getStatus() == 0).mapToLong(InventoryVO::getWillQuantity).sum();
      inventory.setTotalWillQuantity(totalWillQuantity);

      long totalTakeUpQuantity = list.stream()
          .filter(inventoryVO -> inventoryVO.getStatus() == 0)
          .mapToLong(InventoryVO::getTakeUpQuantity)
          .sum();
      inventory.setTotalTakeUpQuantity(totalTakeUpQuantity);

      inventory.setTotalQuantity(totalPhysicalQuantity - totalWillQuantity - totalTakeUpQuantity);
    });

    return PageVO.toPageVo(page);
  }

  private QueryWrapper<SkuInventoryVO> buildEntityWrapper(PageParamsVO pageParamsVO, SkuInventoryVO skuInventory) {
    QueryWrapper<SkuInventoryVO> entityWrapper = pageParamsVO.getEntityWrapper("t");
    String skuNumber = skuInventory.getSkuNumber();
    if (StringUtils.isNotBlank(skuNumber)) {
      entityWrapper.in("ps.number", skuNumber.split("\n"));
    }
    String skuName = skuInventory.getSkuName();
    entityWrapper.like(StringUtils.isNotBlank(skuName), "ps.name", skuName);
    return entityWrapper;
  }

  @Override
  public PageVO<InventoryWaterVO> queryWaterPage(PageParamsVO pageParamsVO, InventoryWaterVO inventoryWaterVO) {
    QueryWrapper<InventoryWaterVO> entityWrapper = pageParamsVO.getEntityWrapper("t");
    String skuNumber = inventoryWaterVO.getSkuNumber();
    if (StringUtils.isNotBlank(skuNumber)) {
      entityWrapper.in("ps.number", skuNumber.split("\n"));
    }
    String skuName = inventoryWaterVO.getSkuName();
    entityWrapper.like(StringUtils.isNotBlank(skuName), "ps.name", skuName);
    String orderSn = inventoryWaterVO.getOrderSn();
    entityWrapper.like(StringUtils.isNotBlank(orderSn), "t.order_sn", orderSn);
    Page<InventoryWaterVO> page = this.baseMapper.getWaterPage(pageParamsVO.getPage(), entityWrapper);
    page.getRecords().forEach(inventoryWater -> {
      //默认库存前后都一样
      inventoryWater.setAfterPhysicalQuantity(inventoryWater.getBeforePhysicalQuantity());
      inventoryWater.setAfterTakeUpQuantity(inventoryWater.getBeforeTakeUpQuantity());
      inventoryWater.setAfterWillQuantity(inventoryWater.getBeforeWillQuantity());
      Integer quantity = inventoryWater.getQuantity();
      Integer changeType = inventoryWater.getChangeType();
      switch (changeType) {
        // 增加欲占
        case InventoryWaterVO.CHANGE_TYPE_WILL:
          //预占库存
          inventoryWater.setAfterWillQuantity(inventoryWater.getBeforeWillQuantity() + quantity);
          break;
        //扣减欲占，增加占用
        case InventoryWaterVO.CHANGE_TYPE_TAKE_UP:
          inventoryWater.setAfterWillQuantity(inventoryWater.getBeforeWillQuantity() - quantity);
          inventoryWater.setAfterTakeUpQuantity(inventoryWater.getBeforeTakeUpQuantity() + quantity);
          break;
        //扣减占用，扣减实物库存
        case InventoryWaterVO.CHANGE_TYPE_PHYSICAL:
          inventoryWater.setAfterTakeUpQuantity(inventoryWater.getBeforeTakeUpQuantity() - quantity);
          inventoryWater.setAfterPhysicalQuantity(inventoryWater.getBeforePhysicalQuantity() - quantity);
          break;
        //修改实物库存
        case InventoryWaterVO.CHANGE_TYPE_MODIFY_PHYSICAL:
          inventoryWater.setAfterPhysicalQuantity((long) quantity);
          break;
        //扣减欲占
        case InventoryWaterVO.CHANGE_TYPE_REJECT:
          inventoryWater.setAfterWillQuantity(inventoryWater.getBeforeWillQuantity() + quantity);
          break;
        //扣减占用
        case InventoryWaterVO.CHANGE_TYPE_SUB_TAKE_UP:
          inventoryWater.setAfterTakeUpQuantity(inventoryWater.getBeforeTakeUpQuantity() - quantity);
          break;
        default:
          log.warn("流水变更类型不正确 {}", inventoryWater);
          break;
      }
    });
    return PageVO.toPageVo(page);
  }

}
